﻿using BCCommon;
using BCCommon.TMS.FreightEnums;
using BCData.Common.Area;
using BCData.TMS.Agent.AgentAreaRecord;
using BCData.TMS.HorsemanFreightConfiguration;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.HorsemanFreightConfiguration;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.HorsemanFreightConfiguration;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace BCService.TMS.HorsemanFreightConfiguration
{
    public class HorsemanFreightConfigurationService : IHorsemanFreightConfigurationService
    {
        private readonly IHorsemanFreightConfigurationData horsemanFreightConfigurationData;
        private readonly ICountyData countyData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.HorsemanFreightConfiguratEntity);
        private readonly IAgentAreaRecordData agentAreaRecordData;  

        public HorsemanFreightConfigurationService(IHorsemanFreightConfigurationData horsemanFreightConfigurationData, ICountyData countyData, IRedisService redisService, IAgentAreaRecordData agentAreaRecordData)
        {
            this.horsemanFreightConfigurationData = horsemanFreightConfigurationData;
            this.countyData = countyData;
            this.redisService = redisService;
            this.agentAreaRecordData = agentAreaRecordData;
        }


        /// <summary>
        /// 新增骑手运费配置信息
        /// </summary>
        /// <param name="admin">当前登录</param>
        /// <param name="dto">骑手运费配置信息</param>
        /// <returns></returns>
        public HorsemanFreightConfigurationDto Add(AdminDto admin, HorsemanFreightConfigurationRequestDto dto)
        {
            var entity = dto.As<HorsemanFreightConfigurationEntity>();

            if (admin.AgentRecord != null)
            {
                if (!dto.CountyId.HasValue)
                {
                    throw new ArgumentException("代理商身份设置运费，区县信息不能为空。");
                }
                var county = this.countyData.GetCounty(dto.CountyId.Value);
                if (county == null)
                {
                    throw new ArgumentException("区县信息不存在。");
                }
                var agentAreaRecord = this.agentAreaRecordData.GetByAgentRecordIdAndCountyCode(admin.AgentRecord.AgentRecordId, county.CountyCode).GetAwaiter().GetResult();
                if (agentAreaRecord != null)
                {
                    throw new ArgumentException($"该区县 {county.CountyCode} 无权限设置。");
                }
                if (this.horsemanFreightConfigurationData.CheckExistsAsync(county.CountyCode).GetAwaiter().GetResult())
                {
                    throw new ArgumentException($"该区县 {county.CountyCode} 已存在运费配置信息了。");
                }
                entity.CountyId = county.CountyId;
                entity.CountyCode = county.CountyCode;
            }
            if (dto.StartWeight <= 0)
            {
                throw new ArgumentException("起步重量不能为空。");
            }
            if (dto.StartDistance <= 0)
            {
                throw new ArgumentException("起步距离不能为空。");
            }
            if (dto.StartPrice <= 0)
            {
                throw new ArgumentException("起步价格不能为空。");
            }
            //总部
            else
            {
                if (dto.CountyId.HasValue)
                {
                    var county = this.countyData.GetCounty(dto.CountyId.Value);
                    if (county == null)
                    {
                        throw new ArgumentException("区县信息不存在。");
                    }
                    entity.CountyId = county.CountyId;
                    entity.CountyCode = county.CountyCode;
                }

            }
            if (dto.IsNight)
            {
                if (dto.NightStartDistance <= 0)
                {
                    throw new ArgumentException("夜间起步距离不能为空。");
                }
                if (dto.NightStartPrice <= 0)
                {
                    throw new ArgumentException("夜间起步价格不能为空。");
                }
                if (dto.NightStartWeight <= 0)
                {
                    throw new ArgumentException("夜间起步重量不能为空。");
                }
                if (dto.NightServiceFee < 0)
                {
                    throw new ArgumentException("夜间服务费不能为空。");
                }
                if (string.IsNullOrWhiteSpace(dto.NightStartTime))
                {
                    throw new ArgumentException("夜间开始时间不能为空。");
                }
                if (string.IsNullOrWhiteSpace(dto.NightEndTime))
                {
                    throw new ArgumentException("夜间结束时间不能为空。");
                }
                Regex regexTime = new Regex(RegexPatterns.TIME);
                Match matchNightStartTime = regexTime.Match(dto.NightStartTime);
                if (!matchNightStartTime.Success)
                {
                    throw new ArgumentException("夜间开始时间格式不正确。");
                }
                Match matchNightEndTime = regexTime.Match(dto.NightEndTime);
                if (!matchNightEndTime.Success)
                {
                    throw new ArgumentException("夜间结束时间格式不正确。");
                }
            }
            else
            {
                entity.NightEndTime = string.Empty;
                entity.NightStartTime = string.Empty;
                entity.NightStartPrice = 0;
                entity.NightStartDistance = 0;
                entity.NightStartWeight= 0;
                entity.NightServiceFee = 0;
            }
            var result = horsemanFreightConfigurationData.InserAsync(entity).GetAwaiter().GetResult();
            if (result == null)
            {
                throw new ArgumentException("运费配置信息新增失败。");
            }
            return result.As<HorsemanFreightConfigurationDto>();
        }

        /// <summary>
        /// 根据区县编码获取骑手运费配置
        /// </summary>
        /// <param name="countyCode">区县编码</param>
        /// <returns></returns>
        public IEnumerable<HorsemanFreightConfigurationDto> GetByCountyCode(string countyCode)
        {
            if (string.IsNullOrWhiteSpace(countyCode))
            {
                string cacheKey = string.Format("{0}:IsBase={1}", key, true);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var data = this.horsemanFreightConfigurationData.GetByCountyCodeAsync().GetAwaiter().GetResult();
                    return data.As<IEnumerable<HorsemanFreightConfigurationDto>>();
                }, TimeSpan.FromDays(365));
                return result;
            }
            else
            {
                string cacheKey = this.redisService.GetKey(key, countyCode);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var data = this.horsemanFreightConfigurationData.GetByCountyCodeAsync(countyCode).GetAwaiter().GetResult();
                    return data.As<IEnumerable<HorsemanFreightConfigurationDto>>();
                }, TimeSpan.FromDays(365));
                return result;
            }
        }

        /// <summary>
        /// 获取指定的骑手运费配置
        /// </summary>
        /// <param name="horsemanFreightConfigurationId">骑手运费配置Id</param>
        /// <returns></returns>
        public HorsemanFreightConfigurationDto GetByHorsemanFreightConfigurationId(long horsemanFreightConfigurationId)
        {
            string cacheKey = this.redisService.GetKey(key, horsemanFreightConfigurationId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.horsemanFreightConfigurationData.GetByHorsemanFreightConfigurationIdAsync(horsemanFreightConfigurationId).GetAwaiter().GetResult();
                return data.As<HorsemanFreightConfigurationDto>();
            }, TimeSpan.FromDays(365));
            return result;
        }

        public PageableList<HorsemanFreightConfigurationViewDto> GetList(AdminDto admin, bool? isBase, string countyCode, DistanceCalculateType? distanceCalculateType, bool? ascending, string sortName, int pageIndex, int pageSize)
        {
            PageableList<HorsemanFreightConfigurationViewDto> result = new PageableList<HorsemanFreightConfigurationViewDto>();
            List<string> countyCodes = new List<string>();
            if (!string.IsNullOrWhiteSpace(countyCode))
            {
                countyCodes.Add(countyCode);
            }
            //代理商先查询，如果没查到返回总部数据
            if (admin.AgentRecord != null)
            {
                var agentAreaRecords = this.agentAreaRecordData.GetByAgentRecordId(admin.AgentRecord.AgentRecordId).GetAwaiter().GetResult();
                countyCodes.AddRange(agentAreaRecords.Select(s => s.CountyCode));
                var queryResult = this.horsemanFreightConfigurationData.GetListAsync(isBase, countyCodes, distanceCalculateType, ascending, sortName, pageIndex, pageSize).GetAwaiter().GetResult();
                if (queryResult.Item1.Any())
                {
                    result = new PageableList<HorsemanFreightConfigurationViewDto>
                    {
                        Items = queryResult.Item1.As<IEnumerable<HorsemanFreightConfigurationViewDto>>(),
                        Count = queryResult.Item2,
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }
                else
                {
                    var data = this.horsemanFreightConfigurationData.GetListAsync(true, countyCodes, distanceCalculateType, ascending, sortName, pageIndex, pageSize).GetAwaiter().GetResult();
                    result = new PageableList<HorsemanFreightConfigurationViewDto>
                    {
                        Items = data.Item1.As<IEnumerable<HorsemanFreightConfigurationViewDto>>(),
                        Count = data.Item2,
                        PageIndex = pageIndex,
                        PageSize = pageSize
                    };
                }
            }
            else
            {
                var data = this.horsemanFreightConfigurationData.GetListAsync(isBase, countyCodes, distanceCalculateType, ascending, sortName, pageIndex, pageSize).GetAwaiter().GetResult();
                result = new PageableList<HorsemanFreightConfigurationViewDto>
                {
                    Items = data.Item1.As<IEnumerable<HorsemanFreightConfigurationViewDto>>(),
                    Count = data.Item2,
                    PageIndex = pageIndex,
                    PageSize = pageSize
                };
            }
            return result;

        }

        /// <summary>
        /// 更新骑手运费配置
        /// </summary>
        /// <param name="admin">当前登录人员</param>
        /// <param name="horsemanFreightConfigurationId">骑手运费配置Id</param>
        /// <param name="dto">骑手运费配置信息</param>
        /// <returns></returns>
        public HorsemanFreightConfigurationDto Update(AdminDto admin, long horsemanFreightConfigurationId, HorsemanFreightConfigurationRequestDto dto)
        {
            bool isExists = this.horsemanFreightConfigurationData.CheckExistsAsync(horsemanFreightConfigurationId).GetAwaiter().GetResult();
            if (!isExists)
            {
                throw new ArgumentException("骑手运费配置不存在。");
            }

            var entity = dto.As<HorsemanFreightConfigurationEntity>();
            if (admin.AgentRecord != null)
            {
                if (!dto.CountyId.HasValue)
                {
                    throw new ArgumentException("代理商身份设置运费，区县信息不能为空。");
                }
                var county = this.countyData.GetCounty(dto.CountyId.Value);
                if (county == null)
                {
                    throw new ArgumentException("区县信息不存在。");
                }
                var agentAreaRecord = this.agentAreaRecordData.GetByAgentRecordIdAndCountyCode(admin.AgentRecord.AgentRecordId, county.CountyCode).GetAwaiter().GetResult();
                if (agentAreaRecord != null)
                {
                    throw new ArgumentException($"该区县 {county.CountyCode} 无权限设置。");
                }
                //if (this.horsemanFreightConfigurationData.CheckExistsAsync(county.CountyCode).GetAwaiter().GetResult())
                //{
                //    throw new ArgumentException($"该区县 {county.CountyCode} 已存在运费配置信息了。");
                //}
                entity.CountyId = county.CountyId;
                entity.CountyCode = county.CountyCode;
            }
            if (dto.StartWeight <= 0)
            {
                throw new ArgumentException("起步重量不能为空。");
            }
            if (dto.StartDistance <= 0)
            {
                throw new ArgumentException("起步距离不能为空。");
            }
            if (dto.StartPrice <= 0)
            {
                throw new ArgumentException("起步价格不能为空。");
            }
            if (dto.IsNight)
            {
                if (dto.NightStartDistance <= 0)
                {
                    throw new ArgumentException("夜间起步距离不能为空。");
                }
                if (dto.NightStartPrice <= 0)
                {
                    throw new ArgumentException("夜间起步价格不能为空。");
                }
                if (dto.NightStartWeight <= 0)
                {
                    throw new ArgumentException("夜间起步重量不能为空。");
                }
                if (dto.NightServiceFee < 0)
                {
                    throw new ArgumentException("夜间服务费不能为空。");
                }
                if (string.IsNullOrWhiteSpace(dto.NightStartTime))
                {
                    throw new ArgumentException("夜间开始时间不能为空。");
                }
                if (string.IsNullOrWhiteSpace(dto.NightEndTime))
                {
                    throw new ArgumentException("夜间结束时间不能为空。");
                }
                Regex regexTime = new Regex(RegexPatterns.TIME);
                Match matchNightStartTime = regexTime.Match(dto.NightStartTime);
                if (!matchNightStartTime.Success)
                {
                    throw new ArgumentException("夜间开始时间格式不正确。");
                }
                Match matchNightEndTime = regexTime.Match(dto.NightEndTime);
                if (!matchNightEndTime.Success)
                {
                    throw new ArgumentException("夜间结束时间格式不正确。");
                }
            }
            else
            {
                entity.NightEndTime = string.Empty;
                entity.NightStartTime = string.Empty;
                entity.NightStartPrice = 0;
                entity.NightStartDistance = 0;
                entity.NightStartWeight = 0;
                entity.NightServiceFee = 0;
            }
            entity.HorsemanFreightConfigurationId = horsemanFreightConfigurationId;
            var result = horsemanFreightConfigurationData.UpdateAsync(entity).GetAwaiter().GetResult();
            if (result == null)
            {
                throw new ArgumentException("运费配置信息更新失败。");
            }
            string cacheKey = this.redisService.GetKey(key, horsemanFreightConfigurationId);
            this.redisService.Delete(cacheKey);
            return result.As<HorsemanFreightConfigurationDto>();
        }
    }
}
